package com.tuuzed.android.dialog;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.ArrayRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.RadioButton;

import com.tuuzed.android.adapter.BaseItemViewBinder;
import com.tuuzed.android.adapter.ItemViewHolder;
import com.tuuzed.android.adapter.RecyclerViewAdapter;
import com.tuuzed.android.adapter.RecyclerViewDivider;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ListDialog extends BaseDialog<ListDialog.Builder> {

    private RecyclerView mRvItem;
    private RecyclerViewAdapter mItemAdapter;
    @Nullable
    private SingleChooseCallback singleChooseCallback = null;
    @Nullable
    private MultiChooseCallback multiChooseCallback = null;

    public static ListDialog newInstance(@NonNull Builder params) {
        ListDialog fragment = new ListDialog();
        fragment.setParams(params);
        fragment.singleChooseCallback = params.singleChooseCallback;
        fragment.multiChooseCallback = params.multiChooseCallback;
        return fragment;
    }

    @Nullable
    @Override
    protected View onContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                                 @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.list_layout, container, false);
        initView(view);
        return view;
    }

    private void initView(View view) {
        mRvItem = view.findViewById(R.id.rv_item);
        mRvItem.addItemDecoration(RecyclerViewDivider.linearLayout(requireContext(), LinearLayoutManager.HORIZONTAL));
        mItemAdapter = new RecyclerViewAdapter().register(Item.class, new ItemViewBinder())
                .attach(mRvItem).clearItems().addItems(mParams.items);
        mItemAdapter.notifyDataSetChanged();
    }

    @Override
    protected View.OnClickListener getPositiveClickListener() {
        return v -> {
            if (mParams.singleChoose) {
                // 单选
                if (singleChooseCallback != null) {
                    int size = mItemAdapter.getItemCount();
                    for (int i = 0; i < size; i++) {
                        Object it = mItemAdapter.getItems().get(i);
                        if (it instanceof Item) {
                            if (((Item) it).checked) {
                                singleChooseCallback.call(((Item) it).item);
                                break;
                            }
                        }
                    }
                }
            } else {
                // 多选
                if (multiChooseCallback != null) {
                    List<String> checkedItems = new ArrayList<>();
                    int size = mItemAdapter.getItemCount();
                    for (int i = 0; i < size; i++) {
                        Object it = mItemAdapter.getItems().get(i);
                        if (it instanceof Item) {
                            if (((Item) it).checked) checkedItems.add(((Item) it).item);
                        }
                    }
                    if (!checkedItems.isEmpty()) {
                        multiChooseCallback.call(checkedItems);
                    }
                }
            }
            if (mParams.positiveClickListener != null) {
                mParams.positiveClickListener.onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
            }
        };
    }

    private class ItemViewBinder extends BaseItemViewBinder<Item> {

        @Override
        public int getLayoutId() {
            return R.layout.list_dialog_item;
        }

        @Override
        public void onBindViewHolder(@NonNull ItemViewHolder holder, @NonNull Item item, int position) {
            if (mParams.singleChoose) {
                holder.find(R.id.cb_check).setVisibility(View.GONE);
                holder.find(R.id.rb_check, RadioButton.class).setChecked(item.checked);
                if (mParams.hideButton) {
                    holder.find(R.id.rb_check).setVisibility(View.GONE);
                } else {
                    holder.find(R.id.rb_check).setVisibility(View.VISIBLE);
                }
            } else {
                holder.find(R.id.rb_check).setVisibility(View.GONE);
                holder.find(R.id.cb_check).setVisibility(View.VISIBLE);
                holder.find(R.id.cb_check, CheckBox.class).setChecked(item.checked);
            }
            holder.text(R.id.tv_item, item.item);
            holder.itemView.setOnClickListener(v -> {
                if (mParams.singleChoose) {
                    // 单选
                    item.checked = true;
                    mItemAdapter.notifyItemChanged(position);
                    int size = mItemAdapter.getItemCount();
                    for (int i = 0; i < size; i++) {
                        if (i == position) continue;
                        Object it = mItemAdapter.getItems().get(i);
                        if (it instanceof Item) {
                            if (!((Item) it).checked) continue;
                            ((Item) it).checked = false;
                            mItemAdapter.notifyItemChanged(i);
                        }
                    }
                    // 选中回调
                    if (singleChooseCallback != null) {
                        singleChooseCallback.call(item.item);
                    }
                    dismiss();
                } else {
                    // 多选
                    item.checked = !item.checked;
                    mItemAdapter.notifyItemChanged(position);
                }
            });
        }
    }

    private static class Item {
        private boolean checked;
        private String item;

        private Item(boolean checked, String item) {
            this.checked = checked;
            this.item = item;
        }
    }

    public interface SingleChooseCallback {
        void call(@NonNull String checkedItem);
    }

    public interface MultiChooseCallback {
        void call(@NonNull List<String> checkedItems);
    }

    public static class Builder extends BaseDialog.Builder<Builder, ListDialog> {
        private List<Item> items;
        private boolean singleChoose;
        private boolean hideButton;
        private String checkedItem;
        private String[] checkedItems;
        private SingleChooseCallback singleChooseCallback = null;
        private MultiChooseCallback multiChooseCallback = null;

        Builder(@NonNull Context context) {
            super(context);
        }

        @NonNull
        @Override
        public ListDialog create() {
            if (items == null) items = Collections.emptyList();
            if (singleChoose) {
                // 单选
                for (Item item : items) {
                    if (!item.item.equals(checkedItem)) continue;
                    item.checked = true;
                    break;
                }
            } else {
                // 多选
                if (checkedItems != null) {
                    for (String checkedItem : checkedItems) {
                        for (Item item : items) {
                            if (!item.item.equals(checkedItem)) continue;
                            item.checked = true;
                            break;
                        }
                    }
                }
            }
            return ListDialog.newInstance(this);
        }

        public Builder items(@ArrayRes int resId) {
            return items(context.getResources().getStringArray(resId));
        }

        public Builder items(String... items) {
            return items(Arrays.asList(items));
        }

        public Builder items(List<String> items) {
            if (items != null) {
                int size = items.size();
                this.items = new ArrayList<>(size);
                for (String it : items) {
                    if (it != null) this.items.add(new Item(false, it));
                }
            }
            return this;
        }

        public Builder singleChoose(String item, SingleChooseCallback chooseCallback) {
            this.singleChooseCallback = chooseCallback;
            this.singleChoose = true;
            checkedItem = item;
            return this;
        }

        public Builder hideButton() {
            this.hideButton = true;
            return this;
        }

        public Builder multiChoose(String[] items, MultiChooseCallback chooseCallback) {
            this.multiChooseCallback = chooseCallback;
            this.singleChoose = false;
            checkedItems = items;
            return this;
        }


    }
}
